package com.wondream.myframework.app.common.util;

import java.io.UnsupportedEncodingException;
import java.util.*;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.slf4j.Logger;


public class MD5Util {

    public static String paySign(Map<String, String> signMap, String merchantKey) {
        StringBuilder builder = new StringBuilder();
        // 获取字典排序后的Entry
        List<Map.Entry<String, String>> infoIds = MapUtil.sortKeys(signMap);
        // 签名字段除sign以外，按照ASCII字典序拼接成形如key1=value1&key2=value2....&keyN=valueN的字符串
        for (Map.Entry<String, String> entry : infoIds) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (StringUtils.equalsIgnoreCase(key, "signature")) {
                continue;
            }
            value = value == null ? "" : value.toString().trim();
            builder.append(key).append("=").append(value).append("&");
        }
        // 在签名串StringA后面拼接商户的API密钥
        builder.append("key="+merchantKey);
        String signData = builder.toString();
        // 对签名串进行MD5加密，转换成大写
        String signature = DigestUtils.md5Hex(signData).toUpperCase();
        return signature;
    }

    public static String apiSign(Map<String, String> signMap, String md5key, Log logger) {
        StringBuilder builder = new StringBuilder();
        // 获取字典排序后的Entry
        List<Map.Entry<String, String>> infoIds = MapUtil.sortKeys(signMap);
        // 签名字段除sign以外，按照ASCII字典序拼接成形如key1=value1&key2=value2....&keyN=valueN的字符串
        for (Map.Entry<String, String> entry : infoIds) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (StringUtils.equalsIgnoreCase(key, "signature")) {
                continue;
            }
            value = value == null ? "" : value.toString().trim();
            builder.append(key).append("=").append(value).append("&");
        }

        builder.append("key="+md5key);
        String signData = builder.toString();
        logger.info(signData);
        // 对签名串进行MD5加密，转换成大写
        String signature = DigestUtils.md5Hex(signData).toUpperCase();
        return signature;
    }


    public static String sign(Map<String, Object> signMap, String md5Key, Logger logger) {
        StringBuffer signdatasb = new StringBuffer();
        Iterator<String> keyIt = signMap.keySet().iterator();
        while (keyIt.hasNext()) {
            String key = keyIt.next();
            if (StringUtils.equalsIgnoreCase(key, "signature")) {
                continue;
            }
            String value = signMap.get(key) == null ? "" : String.valueOf(signMap.get(key));
            signdatasb.append("&").append(key).append("=").append(value);
        }

        String signdata = signdatasb.substring(1) + "&key=" + md5Key;
        logger.debug("签名报文：[{}]", signdata);
        return DigestUtils.md5Hex(signdata);
    }

    /**
     * 字符串签名
     * @param sinStr
     * @param md5Key
     * @param logger
     * @return
     */
    public static String sign(String  sinStr, String md5Key, Logger logger) {
        String signdata =sinStr + md5Key;
        logger.debug("联机签名明文：[{}]", signdata);
        logger.debug("联机签名密文：[{}]", DigestUtils.md5Hex(signdata));
        return DigestUtils.md5Hex(signdata);
    }

    public static boolean verify(Map<String, Object> signMap, String md5Key, String signature, Logger logger) {
    	/*String signResult = MD5Util.sign(signMap, md5Key, logger);
        System.out.println("signResult:"+signResult+",signature:"+signature);
        return StringUtils.equals(signature, signResult);*/
        return StringUtils.equals(signature, MD5Util.sign(signMap, md5Key, logger));
    }

    public static boolean verify(String sinStr, String md5Key, String signature, Logger logger) {
        return StringUtils.equalsIgnoreCase(signature, MD5Util.sign(sinStr, md5Key, logger));
    }

    /**
     *
     * @param signMap
     * @param md5Key
     * @param
     * @param logger
     * @return
     */
    public static boolean verifySort(Map<String, Object> signMap, String md5Key, Logger logger){

        Map<String, Object> resDataMap = new TreeMap<String, Object>(new Comparator<String>() {
            public int compare(String obj1, String obj2) {
                return obj1.compareTo(obj2);
            }
        });
        resDataMap.putAll(signMap);

        return MD5Util.verify(resDataMap, md5Key, (String)signMap.get("signature"), logger);

    }

    public static String sign2(Map<String, String> signMap, String md5Key, Logger logger) {
        StringBuffer signdatasb = new StringBuffer();
        Iterator<String> keyIt = signMap.keySet().iterator();
        while (keyIt.hasNext()) {
            String key = keyIt.next();
            String value = signMap.get(key) == null ? "" : String.valueOf(signMap.get(key));
            signdatasb.append("&").append(key).append("=").append(value);
        }

        String signdata = signdatasb.substring(1) + "&key=" + md5Key;
        logger.debug("签名报文：[{}]", signdata);
        return DigestUtils.md5Hex(signdata);
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        String data = "appid=wx2cc328c53139c487&attach=home0001&auth_code=11&body=超市购物&mch_id=1315513901&nonce_str=z67oupqhwd4ato7s3993coztargzge2x&out_trade_no=S20160719183301002276&sdk_version=java sdk 1.0.1&spbill_create_ip=127.0.0.1&sub_mch_id=1338052301&total_fee=1&key=b8f19c246c4ffe34ba2911434b32e284";
        System.out.println(DigestUtils.md5Hex(data));
        System.out.println(DigestUtils.md5Hex(data.getBytes("GBK")));
    }

}